#include "CEmitter.h"
#include <math.h>
#include "SGD Wrappers/CSGD_Direct3D.h"
#include "CParticle.h"

CEmitter::CEmitter()
{
	m_fParticleTimer = 0;
	m_pEmitterID = NULL;
}
CEmitter::~CEmitter()
{
	if(m_pEmitterID != NULL)
	{
		delete m_pEmitterID;
		m_pEmitterID = NULL;
	}

	for(unsigned int i = 0; i < m_vParticles.size(); ++i)
			delete m_vParticles[i];
}

DWORD* CEmitter::GetColor(int ColorID)
{
	DWORD* colorPalette = new DWORD[ColorID];

    double colorFactor = 100.0f / (float)ColorID / 100.0f;

    for (int colorLevel = 0; colorLevel < ColorID; colorLevel++)
    {

        double endColorQuantity = (colorLevel + 1) * colorFactor;

        double startColorQuantity = 1 - endColorQuantity;

        colorPalette[colorLevel] = D3DCOLOR_ARGB(
        abs((int)(m_nParticleEndAlpha * endColorQuantity + m_nParticleStartAlpha * startColorQuantity)),

        abs((int)(m_nParticleEndRed * endColorQuantity + m_nParticleStartRed * startColorQuantity)),

        abs((int)(m_nParticleEndGreen * endColorQuantity + m_nParticleStartGreen * startColorQuantity)),

        abs((int)(m_nParticleEndBlue * endColorQuantity + m_nParticleStartBlue * startColorQuantity)));
    }
    return colorPalette;
}
void CEmitter::Update(float fElapsedTime)
{
	m_nEmitterLife -= fElapsedTime*1000;

	if(m_nEmitterLife <= 0 && !m_bLooping)
	{
		m_bIsActive = false;
	}
	else
	{
		vector<CParticle*> temp_particles;
		for(unsigned int i = 0; i < m_vParticles.size(); ++i)
		{	
				m_vParticles[i]->Update(fElapsedTime);
			if(m_vParticles[i]->GetIsActive())
				temp_particles.push_back(m_vParticles[i]);
			else
				delete m_vParticles[i];
		}

		m_vParticles.clear();
		m_vParticles = temp_particles;

			for(unsigned int i = 0; i < m_nParticlesPerSec; ++i)
			{
				float PosX = 0;
				float PosY = 0;

				int a;
				switch(m_nEmitterType)
				{
				case 0:
					if(m_nEmitterSize!= 0)
					{
						PosX = (rand()%m_nEmitterSize) + m_fPosX;
						PosY = (rand()%m_nEmitterSize) + m_fPosY;
					}
					else
					{
						PosX = m_fPosX + (rand()%10);
						PosY = m_fPosY + (rand()%10);
					}
					break;
				case 1:
					if(m_nEmitterSize!=0)
					{
						a = (rand()%m_nEmitterSize) + 1;
						PosX = ((rand()%a) - (a/2)) + m_fPosX;
						PosY = (((rand()%a) - (a/2)) * sin((float)(rand()%360))) + m_fPosY;
					}
					else
					{
						PosX = m_fPosX + (rand()%10);
						PosY = m_fPosY + (rand()%10);
					}
					break;
				case 2:
					a = rand()%360;
					PosX = (m_nEmitterSize * sin((float)a)) + m_fPosX;
					PosY = (m_nEmitterSize * cos((float)a)) + m_fPosY;
					break;
				case 3:
					a = rand()%360;
					PosX = (m_nEmitterSize * abs(sin((float)a))) + m_fPosX;
					PosY = m_fPosY;
					break;
				case 4:
					a = rand()%360;
					PosX = m_fPosX;
					PosY = (m_nEmitterSize * abs(cos((float)a))) + m_fPosY;
					break;
				}

				float VelX = 0;
				if(m_fParticleVelMaxX != m_fParticleVelMinX)
					VelX = (rand()% (int)(m_fParticleVelMaxX - m_fParticleVelMinX)) + m_fParticleVelMinX;
				else
					VelX = m_fParticleVelMinX;

				float VelY = 0;
				if(m_fParticleVelMaxY != m_fParticleVelMinY)
					VelY = (rand()% (int)(m_fParticleVelMaxY - m_fParticleVelMinY)) + m_fParticleVelMinY;
				else
					VelY = m_fParticleVelMinY;

				float AccelX = 0;
				if(m_fParticleAccelMaxX != m_fParticleAccelMinX)
					AccelX = (rand()% (int)(m_fParticleAccelMaxX - m_fParticleAccelMinX)) + m_fParticleAccelMinX;
				else
					AccelX = m_fParticleAccelMinX;

				float AccelY = 0;
				if(m_fParticleAccelMinY != m_fParticleAccelMaxY)
					AccelY = (rand()% (int)(m_fParticleAccelMaxY - m_fParticleAccelMinY)) + m_fParticleAccelMinY;
				else
					AccelY = m_fParticleAccelMinY;

				int Life = 0;

				if((m_nParticleLifeMax - m_nParticleLifeMin)!= 0)
					Life = (rand()%(m_nParticleLifeMax - m_nParticleLifeMin)) + m_nParticleLifeMin;
				else
					Life = m_nParticleLifeMin;

				DWORD* ColorArray = GetColor(100);

				m_vParticles.push_back(new CParticle(PosX, PosY, VelX, VelY, AccelX, AccelY, m_fParticleStartScale, m_fParticleEndScale, Life,
					m_nParticleLifeMax, ColorArray, this, m_nParticleImageID));
		}
	}
}

void CEmitter::Render()
{
	CSGD_Direct3D::GetInstance()->DeviceEnd();
	CSGD_Direct3D::GetInstance()->SpriteEnd();
	CSGD_Direct3D::GetInstance()->DeviceBegin();
	CSGD_Direct3D::GetInstance()->SpriteBegin();

	switch(m_nSourceBlendID)
	{
	case 0:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BLENDFACTOR);
		break;
	case 1:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BOTHINVSRCALPHA);
		break;
	case 2:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_BOTHSRCALPHA);
		break;
	case 3:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
		break;
	case 4:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
		break;
	case 5:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVBLENDFACTOR);
		break;
	case 6:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTALPHA);
		break;
	case 7:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR);
		break;
	case 8:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);
		break;
	case 9:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCCOLOR);
		break;
	case 10:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
		break;
	case 11:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
		break;
	case 12:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHASAT);
		break;
	case 13:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
		break;
	case 14:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
		break;
	}
	switch(m_nDestinationBlendID)
	{
	case 0:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_BLENDFACTOR);
		break;
	case 1:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_BOTHINVSRCALPHA);
		break;
	case 2:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_BOTHSRCALPHA);
		break;
	case 3:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
		break;
	case 4:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTCOLOR);
		break;
	case 5:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVBLENDFACTOR);
		break;
	case 6:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
		break;
	case 7:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTCOLOR);
		break;
	case 8:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
		break;
	case 9:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
		break;
	case 10:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
		break;
	case 11:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);
		break;
	case 12:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHASAT);
		break;
	case 13:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
		break;
	case 14:
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
		break;
	}

	for(unsigned int i = 0; i < m_vParticles.size(); ++i)
		m_vParticles[i]->Render();

	/*CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);*/
	CSGD_Direct3D::GetInstance()->DeviceEnd();
	CSGD_Direct3D::GetInstance()->SpriteEnd();
	CSGD_Direct3D::GetInstance()->DeviceBegin();
	CSGD_Direct3D::GetInstance()->SpriteBegin();
}